#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <pthread.h> // 原生线程库的头文件

using namespace std;

const int threadnum = 5;
// 执行任务
class Task
{
public:
    Task()
    {
    }

    void SetTask(int x, int y)
    {
        _x = x;
        _y = y;
    }

    int Excute()
    {
        return _x + _y;
    }

    ~Task()
    {
    }

private:
    int _x;
    int _y;
};

// 进程数据信息
class ThreadData : public Task
{
public:
    ThreadData(int x, int y, const string &threadname)
        : _threadname(threadname)
    {
        _t.SetTask(x, y);
    }

    string Name()
    {
        return _threadname;
    }

    int Run()
    {
        return _t.Excute();
    }

private:
    string _threadname;
    Task _t;
};

class Result
{
public:
    Result()
    {
    }

    void SetResult(int res, const string &threadname)
    {
        _res = res;
        _threadname = threadname;
    }

    void Print()
    {
        cout << _threadname << ":" << _res << endl;
    }

private:
    int _res;
    string _threadname;
};

void *threadrun(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    string name = td->Name();

    Result *res = new Result();
    int ret = td->Run();

    res->SetResult(ret, name);

    delete td;
    return (void*)res;
}

int main()
{
    vector<pthread_t> threads;
    for (int i = 0; i < threadnum; i++)
    {
        char threadname[64];
        snprintf(threadname, sizeof(threadname), "Thread-%d", i + 1);
        ThreadData *td = new ThreadData(10, 20, threadname);

        pthread_t tid;
        pthread_create(&tid, nullptr, threadrun, (void *)td);
        //pthread_create(&tid, nullptr, threadrun, td);
        threads.push_back(tid);
    }

        std::vector<Result *> result_set;
        void *ret = nullptr;
        for (auto tid : threads)
        {
            pthread_join(tid, &ret);//等待线程结束并回收
            result_set.push_back((Result *)ret);//把每个线程的返回值插入数组中
        }

        for (auto res : result_set)
        {
            res->Print();//打印数组中每一个result元素
            delete res;
        }
    return 0;
}

// 同一个进程中的线程，大部分资源是共享的
// 但是也有私有的情况：1.线程的硬件上下文（CPU寄存器的值------负责调度） 2.线程的独立栈结构（负责常规运行）
// 共享：1.代码和全局数据 2.进程文件描述符表

// 线程退出：
// 1.代码跑完，结果正确
// 2.代码跑完，结果错误
// 3.线程异常--------多线程中，任何一个线程异常那么所有线程都退出！！！！！
//  void* threadrun(void* argc)
//  {
//      //cout<<"I am a new thread"<<endl;
//      string threadname=(char*)argc;
//      int cnt=10;
//      while(cnt)
//      {
//          cout<<"the new thread is running: "<<cnt
//          <<",pid:"<<getpid()
//          <<",new thread id:"<<pthread_self()<<endl;

//         sleep(1);
//         cnt--;
//     }

//     return (void*)123;
// }

// //主线程退出==线程退出==所有线程都要推出
// //1.往往我们需要主线程最后退出
// //2.线程要被等待回收
// int main()
// {
//     //1.id
//     pthread_t tid;
//     pthread_create(&tid,nullptr,threadrun,(void*)"thread-1");
//     //cout<<"I am a main thread"<<endl;

//     void* ret=nullptr;

//     //2.
//     int cnt=5;
//     while(cnt)
//     {
//         cout<<"the main thread is running: "<<cnt
//         <<",pid:"<<getpid()
//         <<",new thread id:"<<tid
//         <<",main thread id"<<pthread_self()<<endl;

//         cout<<"---------------------------------"<<endl;
//         sleep(1);
//         cnt--;
//     }

//     //像进程一样：主线程需要等待其他线程，不然会出现内存泄漏问题
//     int n=pthread_join(tid,&ret);
//     cout<<"main thread quit,n="<<n<<",main thread get a ret:"<<(long long)ret<<endl;

//     return 0;
// }